module type Data_t =
sig
    type t
    type input_t
    type output_t
    val convert: t -> output_t
end

module type Data_fun_t =
sig
    include Data_t
    type 'a representation
    val map: f:('a -> 'b) -> 'a representation -> 'b representation
    val iter: f:('a -> unit) -> 'a representation -> unit
end

let id a = a

(** functor, that defines 2 processig functions for data structures,
 such as (data,function) list.
 For example 'data' is histogram and 'function input_data h1' 
 fills histogram 'h1'. 
 This functor is created mostly for performance reasons at now *)

module Unit (DF: Data_fun_t) =
struct
    type processed_t = 
        (DF.t * (DF.input_t -> DF.t -> unit)) DF.representation
    let apply (x: processed_t) (in_data: DF.input_t) = 
        DF.iter x ~f:(fun (data,f) -> f in_data data)
    let get_data (x: processed_t): 'b DF.representation = 
        DF.map x ~f:(fun (data,_) -> DF.convert data) 
end
;;

module DF_list (T: Data_t) =
    Unit
    (struct
        include T
        type 'a representation = 'a list
        let map ~f l = ListLabels.map ~f l
        let iter ~f l = ListLabels.iter ~f l
    end)

